什么是自定义协议驱动开发指导

您所在的位置:网站首页 SDK 驱动 缩写 什么是自定义协议驱动开发指导

什么是自定义协议驱动开发指导

2024-04-13 02:36| 来源: 网络整理| 查看: 265

概述

本文档指导自定义协议驱动开发人员,了解物联网设备接入相关知识,并且可以根据设备接入SDK开发驱动,实现设备物模型定义的功能。

1.了解物联网设备接入1.1 设备接入概念

设备接入是Link IoT Edge提供的基础能力,设备接入模块在Link IoT Edge中称为驱动(driver)或设备接入驱动。所有连接到Link IoT Edge的设备都需要通过驱动实现接入。

设备接入驱动在Link IoT Edge框架位置如图所示。

设备接入框架图1.2 设备接入驱动

1.2.1 设备接入驱动的功能组成

一个完整的驱动(设备接入模块)由设备的连接管理、设备的数据(协议)转换和设备的数据与命令处理三个模块组成。

1.2.1.1连接管理

指设备与网关建立通信连接。Link IoT Edge不限制建立通信连接的协议,可根据业务需求灵活选择。

1.2.1.2数据转换

指设备接入驱动将获取到的终端设备数据转换为符合阿里云IoT物模型规范的数据格式,并上报到阿里云IoT Cloud。阿里云物联网平台物模型规范请参考物模型。

1.2.1.3数据与命令处理

指驱动可以处理云端对于设备的操作请求,并完成对设备的服务调用和处理调用结果,最终将结果返回到阿里云物联网平台。

1.2.2 设备接入驱动的开发工作

设备接入驱动是Link IoT Edge中独立的服务模块,您可以根据业务协议需求开发自定义设备接入驱动。下图展示了自定义驱动的功能和数据流向,并指出了开发一个自定义驱动需要做的开发工作。

IoT框架2.驱动开发

Link IoT Edge提供设备接入SDK(Link Edge Device Access,简称LEDA)方便您开发自己的驱动,SDK目前支持C、Node.js、Java和Python四种版本的语言。

2.1 LEDA接口介绍

LEDA支持的四种开发语言详细内容,请参见C、Node.js、Java和Python。

虽然SDK版本不同,但提供的功能是一样的,LEDA接口调用关系如下图所示:

image

2.2 驱动编码示例

在驱动开发过程中进行驱动编码时,需遵循物联网边缘计算的驱动编码规范和步骤。

2.2.1 驱动和设备配置

进行驱动编码前,需要了解Link IoT Edge的设备信息配置和驱动信息配置相关内容。

2.2.1.1 驱动配置

驱动信息配置在阿里云物联网平台进行配置。部署边缘实例时,驱动配置信息会被部署到边缘网关,其内容以JSON格式存储在Link IoT Edge配置中心,可以通过leda_get_driver_info接口获取。

驱动信息配置为JSON格式:

{ "json":{ "ip":"127.0.0.1", "port":54321 } }

格式参数说明如下:

参数名称

说明

json

驱动配置的格式为JSON格式配置。配置内容为自定义内容。

驱动配置示例:

image

2.2.1.2 设备配置

设备信息配置在阿里云物联网平台控制台配置。部署边缘实例时,设备信息配置会被部署到边缘网关,其内容以JSON格式存储,可以通过leda_get_device_info接口获取。

设备信息配置格式定义:

{ "deviceList": [{ "custom": { "ip":"127.0.0.1", "port":22322 }, // 设备自定义配置 "productKey": "xxxxxxxxxxx", // 产品ProductKey,在创建产品时生成 "deviceName": "demo_led", // 设备DeviceName,在创建设备时设置 }] }

设备信息配置参数说明:

配置名称

配置解释

deviceList

当前驱动下所有已进行设备配置的设备列表。

custom

设备自定义配置。

productKey

设备所在产品唯一标识符。

deviceName

设备名称。

实际设备配置示例:

image

2.2.2 驱动代码示例

完成驱动编码,可参考以下4个示例。本示例的完整工程源码请参见Github源码库LED设备驱动。

2.2.2.1 初始化驱动资源

调用leda_init接口完成资源初始化。

int main(int argc, char** argv) { ... /* init driver */ if (LE_SUCCESS != (ret = leda_init(WORKER_THREAD_NUMS))) { log_e(TAG_NAME_LED_DRIVER, "leda_init failed\n"); return ret; } ... return LE_SUCCESS; }

2.2.2.2 解析驱动配置,完成设备上线

通过调用leda_get_driver_info接口获取驱动配置,解析设备的连接信息,并根据解析结果连接设备。设备连接成功后,调用leda_get_device_info接口获取设备配置并解析,根据解析结果验证设备功能。功能验证通过后,调用leda_register_and_online_by_device_name接口完成设备注册并上线到阿里云物联网平台。

static int online_devices() { ... /* 获取驱动和设备配置 */ size = leda_get_device_info_size(); if (size >0) { device_config = (char*)malloc(size); if (NULL == device_config) { log_e(TAG_DEMO_LED, "allocate memory failed\n"); return LE_ERROR_INVAILD_PARAM; } if (LE_SUCCESS != (ret = leda_get_device_info(device_config, size))) { log_e(TAG_DEMO_LED, "get device config failed\n"); return ret; } } /* 解析驱动和设备配置 */ devices = cJSON_Parse(device_config); if (NULL == devices) { log_e(TAG_DEMO_LED, "device config parser failed\n"); return LE_ERROR_INVAILD_PARAM; } cJSON_ArrayForEach(item, devices) { if (cJSON_Object == item->type) { /* 解析配置内容 */ result = cJSON_GetObjectItem(item, "productKey"); productKey = result->valuestring; result = cJSON_GetObjectItem(item, "deviceName"); deviceName = result->valuestring; result = cJSON_GetObjectItem(item, "custom"); if (NULL != result) { log_i(TAG_DEMO_LED, "custom content: %s\n", cJSON_Print(result)); } /* 注册并上线设备 */ device_cb.get_properties_cb = get_properties_callback_cb; device_cb.set_properties_cb = set_properties_callback_cb; device_cb.call_service_cb = call_service_callback_cb; device_cb.service_output_max_count = 5; dev_handle = leda_register_and_online_by_device_name(productKey, deviceName, &device_cb, NULL); if (dev_handle < 0) { log_e(TAG_DEMO_LED, "product:%s device:%s register failed\n", productKey, deviceName); continue; } g_dev_handle = dev_handle; log_i(TAG_DEMO_LED, "product:%s device:%s register success\n", productKey, deviceName); } } ... return LE_SUCCESS; }

2.2.2.3 上报数据

将收到的设备数据转换为阿里云IoT物模型格式并上报到物联网平台,调用leda_report_properties接口上报设备属性数据,调用leda_report_event接口上报设备事件。

/* 上报数据 */ while (1) { /* 上报属性 */ leda_device_data_t dev_proper_data[1] = { { .type = LEDA_TYPE_INT, .key = {"temperature"}, .value = {0} } }; sprintf(dev_proper_data[0].value, "%d", g_dev_temperature); leda_report_properties(g_dev_handle, dev_proper_data, 1); /* 上报事件 */ if (g_dev_temperature > 50) { leda_device_data_t dev_event_data[1] = { { .type = LEDA_TYPE_INT, .key = {"temperature"}, .value = {0} } }; sprintf(dev_event_data[0].value, "%d", g_dev_temperature); leda_report_event(g_dev_handle, "high_temperature", dev_event_data, 1); } sleep(5); }

2.2.2.4 处理云端服务请求

实现服务请求的三个回调函数如下所示。

get接口:处理获取设备属性的请求。

set接口:处理设置设备属性的请求。

service接口:处理调用设备自定义方法的请求。

static int get_properties_callback_cb(device_handle_t device_handle, leda_device_data_t properties[], int properties_count, void *usr_data) { ... return ret; } static int set_properties_callback_cb(device_handle_t device_handle, const leda_device_data_t properties[], int properties_count, void *usr_data) { ... return ret; } static int call_service_callback_cb(device_handle_t device_handle, const char *service_name, const leda_device_data_t data[], int data_count, leda_device_data_t output_data[], void *usr_data) { ... return ret; }

2.3 驱动产出方式

2.3.1 驱动依赖注意事项

设备接入驱动根据协议和业务场景的不同,可能会涉及第三方库依赖。Link IoT Edge针对开发设备接入驱动所用不同开发语言,分别制定了第三方库依赖规则。

C版本SDK:C语言属于编译型语言,如果编译目标环境和运行环境不一致,则很可能导致不可运行。所以对于使用设备接入C版本SDK开发驱动,需要保证开发编译目标环境和运行环境相同。 驱动包中包含驱动程序和依赖动态库。如果该驱动依赖于第三方库,则需要将动态库和驱动程序一起打包生成最终驱动程序包。

Node.js版本SDK:使用设备接入SDK Node.js版本开发驱动时,若依赖第三方库,需要到Link IoT Edge运行环境上开发驱动,并在驱动目录中使用如下命令安装依赖。

npm install 第三方库名

Python版本SDK:使用设备接入SDK Python版本开发驱动时,若依赖第三方库,需要到Link IoT Edge运行环境上开发驱动,并在驱动目录中使用如下命令安装依赖。

pip3 install -t . 第三方库名

2.3.2 驱动打包方式

基于Link IoT Edge提供的SDK开发驱动并完成调试后,需将产物打包为.zip包,并确保驱动Binary或index源文件在.zip包第一级目录。

每个版本SDK开发的驱动在打包时,有不同的打包规则。

基于C SDK开发的驱动对于C语言开发的驱动,驱动包中包含驱动程序和驱动依赖的动态库。如果驱动程序包含依赖库,则需要将依赖库放置指定的位置,即在驱动程序当前路径下的lib文件夹下。具体操作步骤如下:

规定驱动程序需命名为main。

在main当前路径下创建lib文件夹。

将main依赖的动态库全部拷贝到lib文件夹下。

使用zip命令对当前路径下的main和lib进行压缩处理生成zip包。

zip -r your_driver_name.zip main lib

基于Python SDK开发的驱动包文件中须包含index.py,并且在该文件中定义handler函数。驱动是一个在函数计算应用引擎中持续运行的函数,所以在驱动包中须包含index.py文件,并且在该文件中定义handler函数。 驱动运行时,会加载index.py文件。而该文件中,函数计算应用定义的handler函数是不会被调用,因此驱动代码须放在handler函数外,保证加载index.py文件时能直接执行。详情请参考Python版本SDK

基于Node.js SDK开发的驱动包文件中须包含index.js,并且在该文件中定义handler函数。 驱动运行时,会加载index.js文件。而该文件中,函数计算应用定义的handler函数是不会被调用,因此驱动代码须放在handler函数外,保证加载index.js文件时能直接执行。详情请参考Nodejs版本SDK

2.4 驱动使用示例

2.4.1 上传及发布驱动

在SI集成工作台si.iot.aliyun.com上,选择边缘接入->驱动管理,选择新增驱动

根据提示设置参数,需要注意的是通信协议类型要选择【自定义】

imageimageimage

上传已完成编译并打包的led_driver.zip文件。

完成参数的设置并上传成功驱动文件后,单击确定。您可以在自研驱动列表中看到刚刚创建的驱动

2.4.2分配驱动和设备到边缘实例

2.4.2.1 添加驱动到边缘实例

登录SI集成工作台si.iot.aliyun.com,在网关管理设备集成页面,点击网关右侧的设置图标,首先,在弹出菜单中选择添加协议

image

然后,在下拉选择的协议列表中选择“DemoDriver”,选择“确定”。

image

2.4.2.2 新建设备

如下图所示,通过点击通道右侧的“设置”图标,选择“新建设备”

image

在弹出的新建设备页面中按照如下方式选择刷卡门禁

image

点击确定按钮即可完成设备创建,创建好的设备如下如所示:

image

2.4.3 部署边缘实例

实例详情页面,右上角单击部署,部署边缘实例。部署成功后边缘实例名称后显示部署成功

image

2.4.4 查看驱动日志

在边缘网关宿主机命令行中通过docker命令进入LE网关运行环境,命令如下:

sudo docker exec -it $(sudo docker ps | grep k8s_linkedge | awk '{print $1}') bash

进入网关容器内之后可以在本地查看驱动日志。

a. 通过./fctl show命令,可以查看到部署驱动的具体位置。

cd /linkedge/gateway/build/bin/ ./fctl show

系统显示类似如下图所示:图1

参数说明:

字段名称

字段解释

DriverName

驱动名称,该名称为在上传及发布驱动步骤中设置的驱动名称。

CodePath

驱动部署到边缘网关中的位置路径。

Process PID

驱动启动后的进程ID。

b. 驱动在运行过程中会产生运行日志,通过查看运行日志可以了解驱动运行状态,每个自定义驱动生成的日志文件统一放在/linkedge/run/logger/fc-base路径下。每个驱动日志文件路径为/linkedge/run/logger/fc-base/xxxx/log_xxxx.txt。

说明驱动日志文件路径中的xxxx为在上传驱动时填写的名称。

cd /linkedge/run/logger/fc-base/demo_driver && ls -l

详情如下图所示:详情

驱动运行日志可以查看大部分驱动的运行状态,但是有时还需要查看其它日志配合了解当前驱动的运行情况,例如设备上线异常时可以查看dimu日志,日志文件路径为/linkedge/run/logger/dimu/log_xxxxx.txt。

cd /linkedge/run/logger/dimu ls -l

详情如下图所示:详情2

设备上线成功后,如果设备数据上报有异常,则可以查看cloud_proxy日志。cloud_proxy产生的运行日志文件路径格式为/linkedge/run/logger/cloud-proxy/log_xxxxx.txt。

cd /linkedge/run/logger/cloud-proxy ls -l

详情如下图所示:详情3

2.5 驱动调试方式

2.5.1 云端在线调试

如果设备上线成功,则可以使用阿里云物联网平台在线调试功能调试驱动和设备,该功能页面还可以实时查看设备上报的数据信息,也可以触发对设备服务的调用请求。

a.在物联网平台控制台,选择监控运维 > 在线调试,在在线调试页面,选择调试产品和调试设备。

b.选择调试设备待调功能和服务,进行调试,并查看设备实时运行日志在线调试

2.5.2 边缘端替换驱动

如果在驱动调试过程中发现问题,需要修改驱动代码重新生成新的驱动进行调试,这时只需要在本地替换修改编译后的驱动即可。

a. 找到驱动的位置。可以通过fctl命令进行查找,具体字段解释查看调试信息。

cd /linkedge/gateway/build/bin/ ./fctl show详情3

b. 根据CodePath找到驱动所在位置路径,完成替换。

c. 根据Process PID得到驱动进程ID,使用kill -9 Pid命令重新启动驱动。

kill -9 Pid #Pid为驱动进程ID,即通过fctl命令查看得到的Process PID



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3